package com.qire.antscompiler;

import com.google.auto.service.AutoService;
import com.qire.antscompiler.generator.DeepLinkCodeGenerator;
import com.qire.antscompiler.utils.Log;
import com.qire.antscore.annotation.DeepLink;
import com.qire.antscore.common.AssertUtils;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

@AutoService(Processor.class)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class DeepLinkProcessor extends AbstractProcessor {

    // 日志工具
    private Log log;
    // 代码生成器
    private DeepLinkCodeGenerator codeGenerator;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        // 获得apt的日志输出
        log = Log.newLog(processingEnv.getMessager());

        // 初始化代码生成器
        codeGenerator = new DeepLinkCodeGenerator(processingEnv);
        log.i("init DeepLinkProcessor success!");
    }

    /**
     * 注解处理过程（责任链模式）
     * @param annotations
     * @param roundEnv
     * @return true 表示当前处理过的注解后续不在处理， false 表示后续依旧会处理
     */
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (AssertUtils.notEmpty(annotations)) {
            // 被 DeepLink 注解的节点集合
            Set<? extends Element> deepLinkElements = roundEnv.getElementsAnnotatedWith(DeepLink.class);
            if (AssertUtils.notEmpty(deepLinkElements)) {
                codeGenerator.parseDeepLink(deepLinkElements);
            }
            return true;
        }
        return false;
    }

    /**
     * 指定这个注解处理器是注册给哪个注解的，这里说明是注解 {@link DeepLink}
     * @return 返回一个包含处理器关注的注解清单，如果扫描中未发现注解清单中的注解则不会执行 {@link #process process(annotations, roundEnv)} 注解处理过程。
     */
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        HashSet<String> supportTypes = new LinkedHashSet<>();
        supportTypes.add(DeepLink.class.getCanonicalName());
        return supportTypes;
    }

}
